package es.udc.acs.consorcio.server;

import es.udc.acs.consorcio.client.DataClient;
import es.udc.acs.consorcio.mensaje.GestorMensaje;
import es.udc.acs.consorcio.mensaje.Mensaje;
import es.udc.acs.consorcio.sesion.GestorSesion;
import es.udc.acs.consorcio.sesion.Sesion;
import es.udc.acs.consorcio.ui.MainConsorcio;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.udp.QuestionServer;
import es.udc.acs.utils.CodigosFAP;
import es.udc.acs.utils.FormateadorDatos;
import es.udc.acs.utils.GestorProperties;

public class CajeroServer implements QuestionServer {

	@Override
	public String procesarPregunta(String pregunta) {
		//cabecera
		String origen;
		String destino;
		String tipo;
		
		String response = "";
		
		origen  = ParserMensaje.obtenerOrigen(pregunta);
		destino = ParserMensaje.obtenerDestino(pregunta);
		tipo	= ParserMensaje.obtenerTipo(pregunta);
		
		if (!MainConsorcio.getDisponible()) {
			return destino + origen + CodigosFAP.NO_RESPUESTA;
		}
		
		FormateadorDatos.formatearMensaje(pregunta,false);
		
		if(!CodigosFAP.esDatos(tipo)){
			
			GestorProperties.tratarMensaje(
					"CajeroServer:mensaje enviado: ",destino + origen + CodigosFAP.CE_OTRAS_CAUSAS);
			
			FormateadorDatos.formatearMensaje(destino+origen+CodigosFAP.CE_OTRAS_CAUSAS,false);
			return destino+origen+CodigosFAP.CE_OTRAS_CAUSAS;
		}
		
		GestorProperties.tratarMensaje("CajeroServer:mensaje recibido: ",pregunta);

		response = obtenerRespuesta(pregunta,tipo);
		
		GestorProperties.tratarMensaje(
				"CajeroServer:mensaje enviado: ",destino + origen + response);
		
		FormateadorDatos.formatearMensaje(destino+origen+response,false);

		return destino + origen + response;
	}


	private String obtenerRespuesta(String pregunta,
			                        String codPregunta) {
		
		String cuerpo     = ParserMensaje.obtenerCuerpo(pregunta);
		String numTarjeta = ParserMensaje.obtenerNumTarjeta(cuerpo);
		String banco	  = ParserMensaje.obtenerBanco(numTarjeta);
		String tarjeta	  = ParserMensaje.obtenerTarjeta(numTarjeta);
		
		String message;
		String response;
		Sesion sesion;
		String subcabecera;
		String tipoRespuesta;
		
		// comprobar q sea un mensaje de datos valido
		if(!codPregunta.equals(CodigosFAP.CM_C_PD_CONSULTAR_SALDO)		
				&& !codPregunta.equals(CodigosFAP.CM_C_PD_CONSULTAR_MOVIMIENTOS)
				&& !codPregunta.equals(CodigosFAP.CM_C_PD_REINTEGRO)
				&& !codPregunta.equals(CodigosFAP.CM_C_PD_ABONO)
				&& !codPregunta.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
			return CodigosFAP.CE_OTRAS_CAUSAS;
		}	
		
		tipoRespuesta = CodigosFAP.obtenerTipoRespuesta(codPregunta);
		
		//Comprobar si el banco tiene sesion abierta y devolver sesion
		sesion = GestorSesion.getSesion(banco);
		if((sesion == null) || sesion.obtenerEstado().equals("Trafico detenido")){
			
			// si no hay sesion algunas se guardan en modo offline
			if (codPregunta.equals(CodigosFAP.CM_C_PD_REINTEGRO)
					|| codPregunta.equals(CodigosFAP.CM_C_PD_ABONO)
					|| codPregunta.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
				
				Mensaje msn = new Mensaje(pregunta, 
						                  banco, 
						                  tarjeta, 
						                  obtenerImporte(cuerpo,codPregunta));
				
				// modo offline, si aceptamos el mensaje o no(sobrepasado importe)
				if (GestorMensaje.addMensaje(msn)) {
					return tipoRespuesta+CodigosFAP.CR_CONSULTA_ACEPTADA;
				} else {
					return tipoRespuesta+CodigosFAP.CR_CONSULTA_DENEGADA;
				}
			}
			
			return tipoRespuesta
				   + CodigosFAP.CR_CONSULTA_DENEGADA;
		}
		
		//Pedir permiso a sesion para ejecutar la pregunta y que nos devuelva
		//el canal
		subcabecera = sesion.sendMessage(GestorProperties.devolverPropiedad(GestorProperties.IDCONSORCIO) 
				                         + banco + codPregunta + "1" + cuerpo);
		if(subcabecera.length() == 2){
			return tipoRespuesta + subcabecera;
		}
		
		//Formar pregunta y mandarla al cliente del Banco.
		message = GestorProperties.devolverPropiedad(GestorProperties.IDCONSORCIO) 
				  + banco + codPregunta + subcabecera + "1" 
				  + cuerpo;
		
		response = DataClient.sendMessage(message, sesion);
		
		if (response == null) {
			return tipoRespuesta + CodigosFAP.CE_OTRAS_CAUSAS;
		}
		
		aumentarMarcadores(sesion,response,codPregunta);
		
		return tipoRespuesta + response;
		
	}
	
	
	private void aumentarMarcadores(Sesion sesion,String res,String tipo) {
		try {
			// para llevar la cuenta del numero de operaciones
			if (res.substring(0, 2).
					equals(CodigosFAP.CR_CONSULTA_ACEPTADA)) {
				
				if (tipo.equals(CodigosFAP.CM_C_PD_REINTEGRO)) {
					sesion.sumarReintegro();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_ABONO)) {					
					sesion.sumarAbono();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
					sesion.sumarTraspaso();		
				}
			}	
		} catch(Exception e) {}
	}

	
	private String obtenerImporte(String cuerpo, String codPregunta) {
		
		if (codPregunta.equals(CodigosFAP.CM_C_PD_REINTEGRO)) {
			return ParserMensaje.obtenerImporte(cuerpo);
		}else if (codPregunta.equals(CodigosFAP.CM_C_PD_ABONO)) {
			return ParserMensaje.obtenerImporte(cuerpo);
		}else if (codPregunta.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
			return ParserMensaje.obtenerImporteTraspaso(cuerpo);
		}
		
		return "";		
	}
}
